<?php

namespace App\Customer\Model;

use App\Facades\UrlCrypt;
use App\Service\Mailer as MailerService;
use App\Web\Facades\UserAuth;
use EchoPHP\Facades\Db;
use EchoPHP\Facades\Log;
use EchoPHP\Validator\Validator;
use Exception;
use Throwable;
use App\Service\Mailer;
use PHPMailer\PHPMailer\Exception as PHPMailerException;

class ResumeRecommend extends Model {
    private $tablename = 'ResumeRecommend';
    protected $field = 'id,subid,caseid,email,title,memo,firstopentime,cc,createdate,updatedate,status,recommender,retrydate';

    /**
     * 查询推荐给我的总记录数
     * @param array $search
     * @return array
     */
    public function getToMyRecommendCount($hruId, $search = []) {
        $field = 'count(1) as count';
        $result = $this->getToMyRecommend($hruId, $field, $search);
        if (empty($result)) {
            return 0;
        }
        return $this->getToMyRecommend($hruId, $field, $search)[0]['count'];
    }


    /**推荐给我的记录
     * @param $customerId
     * @param $field
     * @param $search
     * @param int $rowFrom
     * @param int $rowTo
     * @return array|null
     */
    public function getToMyRecommend($hruId, $field = '', $search = [], $rowFrom = 0, $rowTo = 0) {
        if (empty($hruId)) {
            return [];
        }
        //查询网才账号RPO客户联系人绑定关系表。
        $sql = 'select id from CustomerAccount where ehireaccid=? and status=?';
        $var = [$hruId, '01'];
        $customerInfo = Db::selectOne($sql, $var);
        if (!isset($customerInfo['id'])) {
            return [];
        }

        $strField = $field != '' ? $field : 'a.id,a.subid,a.caseid,a.title,a.memo,a.firstopentime,a.createdate,a.updatedate,a.status';

        $sql = 'select ' . $strField . ' from ResumeRecommend a INNER JOIN ResumeRecommendCustomer b on a.id = b.recommendid ';
        $sql .= ' where b.customerid in (select id from CustomerAccount where ehireaccid=? and status=?) and a.status=? and b.status=? ';

        $var = [$hruId, '01', '01', '01'];

        if (isset($search['createdatebegin']) && !empty($search['createdatebegin'])) {
            $sql .= ' and b.createdate >= ? ';
            $var[] = $search['createdatebegin'] . ' 00:00:00';
        }
        if (isset($search['createdateend']) && !empty($search['createdateend'])) {
            $sql .= ' and b.createdate <= ? ';
            $var[] = $search['createdateend'] . ' 23:59:59';
        }

        if (isset($search['createdatebegin']) && !empty($search['createdatebegin'])) {
            $sql .= ' and a.createdate >= ? ';
            $var[] = $search['createdatebegin'] . ' 00:00:00';
        }
        if (isset($search['createdateend']) && !empty($search['createdateend'])) {
            $sql .= ' and a.createdate <= ? ';
            $var[] = $search['createdateend'] . ' 23:59:59';
        }
        if (isset($search['subId']) && !empty($search['subId'])) {
            $sql .= ' and a.subid = ? ';
            $var[] = $search['subId'];
        }

        $sql .= ' ORDER BY a.id desc';
        return Db::select($sql, $var, $rowFrom, $rowTo);
    }

    /**
     * 查询我发送的推荐总记录数
     * @param array $search
     * @return array
     */
    public function getMyRecommendCount($search = []) {
        $field = 'count(1) as count';
        return $this->getMyRecommend($field, $search)[0]['count'];
    }


    /**我发送的推荐记录
     * @param $field
     * @param $search
     * @param int $rowFrom
     * @param int $rowTo
     * @param string $orderBy
     * @return array|null
     */
    public function getMyRecommend($field, $search, $rowFrom = 0, $rowTo = 0, $orderBy = '') {
        $user = UserAuth::getLoginInfo();
        if (empty($search['creator']) && empty($search['id'])) {
            return null;
        }

        $field = $field ?: $this->field;
        $sql = 'SELECT ' . $field . ' FROM ' . $this->tablename . ' as rr left join CustomerSub as s on rr.subid = s.subid';
        $where = '';
        $var = [];
        if (!empty($search['id'])) {
            $where .= ' WHERE id = ?';
            $var[] = $search['id'];
        } else {
            if ($user['issuper'] != 1) {
                $where .= ' WHERE recommender = ?';
                $var[] = $search['creator'];
            } else {
                $where .= ' WHERE 1=1 ';
            }

            if (!empty($search['subname'])) {
                $where .= ' and s.subname like ? ';
                $var[] = "%" . $search['subname'] . "%";
            }

            if (!empty($search['crmsubid'])) {
                $where .= ' and s.crmsubid = ? ';
                $var[] = $search['crmsubid'];
            }

            if (!empty($search['title'])) {
                $where .= ' and rr.title like ? ';
                $var[] = "%" . $search['title'] . "%";
            }

            if (!empty($search['status']) && $search['status'] != '00') {
                $where .= ' and rr.status = ? ';
                $var[] = $search['status'];
            }

            if (!empty($search['caseid'])) {
                $where .= ' and caseid like ? ';
                $var[] = "%" . $search['caseid'] . "%";
            }

            if (isset($search['createdatebegin']) && !empty($search['createdatebegin'])) {
                $where .= ' and rr.createdate >= ? ';
                $var[] = $search['createdatebegin'] . ' 00:00:00';
            }
            if (isset($search['createdateend']) && !empty($search['createdateend'])) {
                $where .= ' and rr.createdate <= ? ';
                $var[] = $search['createdateend'] . ' 23:59:59';
            }
        }

        $sql .= $where;
        $sql .= empty($orderBy) ? ' ORDER BY id desc' : (' ORDER BY ' . $orderBy);

        return Db::select($sql, $var, $rowFrom, $rowTo);
    }

    /*
     * 根据批次ID获取推荐记录
     */
    public function getCaseIdFromRecommend($id, $field) {
        if (empty($id) || !is_numeric($id)) {
            return null;
        }

        $sql = 'SELECT ' . $field . ' FROM ' . $this->tablename . ' WHERE id = ? ';
        $var = [$id];
        return Db::selectOne($sql, $var);
    }

    /*
     * 设置推荐记录首次读取时间
     */
    public function setRecommendReadTime($id) {
        if (empty($id)) {
            return null;
        }

        $var = array_filter(explode(',', $id));
        if (empty($var)) {
            return null;
        }

        $inFlag = substr(str_repeat('?,', count($var)), 0, -1);
        $sql = 'UPDATE ' . $this->tablename . ' set firstopentime = IFNULL(firstopentime,NOW()), updatedate = NOW() WHERE id in(' . $inFlag . ')';
        Db::update($sql, $var);
    }

    /**
     * 推荐数据校验
     * @param $emailParams
     * @return array
     */
    public function recommendParamsValidate($emailParams) {
        $rule = [
            'email|收件人' => ['required', 'minLength' => '5', 'maxLength' => '500'],
            'cc|抄送人' => ['maxLength' => '500'],
            'title|邮件主题' => ['required', 'minLength' => '1', 'maxLength' => '100'],
            'content|邮件正文' => ['required', 'maxLength' => '1000']
        ];
        $msg = [];
        $validate = new Validator($rule, $msg);
        $result = $validate->validate([
            'title' => isset($emailParams['title']) ? $emailParams['title'] : '',
            'email' => isset($emailParams['email']) ? $emailParams['email'] : '',
            'cc' => isset($emailParams['cc']) ? $emailParams['cc'] : '',
            'content' => isset($emailParams['content']) ? $emailParams['content'] : '',
        ]);
        if (!$result) {
            return ['status' => false, 'message' => '校验失败', 'errorFields' => $validate->getErrors()];
        }

        $emails = explode(';', $emailParams['email']);
        $emails = array_filter($emails);
        if (count($emails) < 1) {
            return ['status' => false, 'message' => '校验失败', 'errorFields' => ['email' => 'Email不合法']];
        }
        $emailParams['email'] = implode(";", $emails);

        return ['status' => true, 'message' => '校验通过'];
    }

    /**
     * 新增推荐简历
     * $params:subid,caseid,email,title,content,creator,creatorname,resumeid,caseresumeid
     * return ['status' => true, 'message' => '保存成功'];
     * @param $oprId
     * @param $oprName
     * @param $subId $projectId
     * @param $caseResumeIds ['caseid', 'resumeid', 'caseresumeid']   职位id，简历id 以及在职位简历关系表中的主键id
     * @param $emailParams      邮箱所需参数
     * @return array
     */
    public function addRecommendTask($oprId, $oprName, $subId, $caseResumeIds, $emailParams) {
        $validateResult = $this->recommendParamsValidate($emailParams);
        if (!$validateResult['status']) {
            return $validateResult;
        }
        $emailParams['creator'] = $oprId;
        $emailParams['creatorname'] = $oprName;
        $emailParams['cc'] = isset($emailParams['cc']) ? $emailParams['cc'] : '';
        //循环遍历简历id
        $caseIds = [];
        foreach ($caseResumeIds as $caseResumeId) {
            $caseIds[] = $caseResumeId['caseid'];
        }
        $caseIds = array_unique($caseIds);
        $emailParams['caseidstring'] = implode(',', $caseIds);

        $recommendId = 0;
        $nowTime = time();
        try {
            Db::connect('jyrpo_pdo')->transaction(function () use ($subId, $caseIds, $emailParams, $caseResumeIds, $nowTime, &$recommendId) {
                $tmpTime = date("Y-m-d H:i:s", $nowTime);

                $inFlag = substr(str_repeat('?,', count($caseIds)), 0, -1);
                $caseIns = 'update SCase set RecmomendDate =? where subid=? and caseid in (' . $inFlag . ')';
                $caseVar = array_merge([$tmpTime, $subId], $caseIds);
                Db::connect('jyrpo_pdo')->update($caseIns, $caseVar);

                $taskIns = "INSERT INTO " . $this->tablename . "(subid,caseid,email,cc,title,recommender,status,createdate,memo,extraparams)VALUES (?,?,?,?,?,?,?,?,?,?)";
                $taskVar = [$subId, $emailParams['caseidstring'], $emailParams['email'], $emailParams['cc'], $emailParams['title'], $emailParams['creator'], '01',
                    $tmpTime, mb_substr($emailParams['content'], 0, 200), json_encode(['showFields' => $emailParams['showfields']])];
                Db::connect('jyrpo_pdo')->insert($taskIns, $taskVar);
                $recommendId = Db::connect('jyrpo_pdo')->getLastInsertId();

                $taskDetailIns = "INSERT INTO ResumeRecommendDetail(recommendid,subid,caseid,resumeid,caseresumeid,creator,creatorname,status,createdate,updatedate)VALUES ";
                $taskDetailVar = [[]];
                foreach ($caseResumeIds as $caseResumeId) {
                    $taskDetailIns .= '(?,?,?,?,?,?,?,?,?,?),';
                    $taskDetailVar[] = [$recommendId, $subId, $caseResumeId['caseid'], $caseResumeId['resumeid'], $caseResumeId['caseresumeid'],
                        $emailParams['creator'], mb_substr($emailParams['creatorname'], 0, 50), '01', $tmpTime, $tmpTime];
                }
                $taskDetailIns = trim($taskDetailIns, ',');
                $taskDetailVar = array_merge(...$taskDetailVar);
                Db::connect('jyrpo_pdo')->insert($taskDetailIns, $taskDetailVar);

                if (isset($emailParams['customerid']) && !empty($emailParams['customerid'])) {
                    $customerIdArr = explode(';', $emailParams['customerid']);
                    $customerIdArr = array_filter(array_unique($customerIdArr));

                    $customerIns = "INSERT INTO ResumeRecommendCustomer(recommendid,customerid,createdate,status)VALUES ";
                    $customerVar = [[]];
                    foreach ($customerIdArr as $customerId) {
                        $customerIns .= '(?,?,?,?),';
                        $customerVar[] = [$recommendId, $customerId, $tmpTime, '01'];
                    }
                    $customerIns = trim($customerIns, ',');
                    $customerVar = array_merge(...$customerVar);
                    Db::connect('jyrpo_pdo')->insert($customerIns, $customerVar);
                }
            });
        } catch (Exception $e) {
            return ['status' => false, 'message' => '保存失败', 'errorFields' => ['db_Exception' => $e->getMessage()]];
        } catch (Throwable $e) {
            return ['status' => false, 'message' => '保存失败', 'errorFields' => ['db_Throwable' => $e->getMessage()]];
        }

        $duetime = strtotime(date("Y-m-d", $nowTime)) + 8 * 86400;
        $url = $this->creatRecommendToken($subId, $recommendId, $duetime);
        $result = $this->sendMail($recommendId, $emailParams['email'], $emailParams['cc'], $emailParams['title'], $emailParams['content'], $url, count($caseResumeIds));
        return $result;
    }

    /**
     * 生成推荐简历链接
     * $params:$recommendid, $subid, $duetime
     * return $token;
     */
    function creatRecommendToken($subId, $recommendId, $duetime, $isTest = '') {
        $keyVerify = [];
        $keyVerify['recommendid'] = $recommendId;
        $keyVerify['subid'] = $subId;
        $token = UrlCrypt::generateToken($keyVerify);
        $url = CUSTOMERHOST . "/feedback?subid=" . $keyVerify['subid'] . "&recommendid=" . $keyVerify['recommendid'] . "&type=1&token=" . $token;
        if (!empty($isTest)) {
            $url .= "&istest=" . $isTest;
        }
        return $url;
    }

    /**
     * 兼容现有的简历详情页面
     * @param $subId
     * @param $resumeid
     * @param $duetime
     * @param $key
     * @return string
     */
    public function creatRecommendResumeUrl($subId, $resumeid, $token) {
        $url = CUSTOMERHOST . "/resumepage?resumeid=". $resumeid. "&subid=". $subId ."&token=". $token . "&type=0";
        return $url;
    }


    /**
     *发送推荐邮件
     * $params:$emails, $cc, $subject, $content, $url
     * return return ['status' => false, 'message' => '邮件发送失败', 'errorMsg' => '收件人不可为空'];
     */
    function sendMail($recommendId, $emails, $cc, $subject, $content, $url, $num) {
        try {
            //出现错误时是否直接抛出异常，如果抛出异常。另外需要异常捕捉程序，默认不开启。
            //$mail = new Mailer(true);
            $mail = new MailerService();
            //！！核心部分，指定通过无忧邮件平台发送
            $mail->isJobsmail(true);
            //非必须，如果有多个收件人，是一起批量发送还是独立发送多份邮件
            $mail->SingleTo = false;
            //后续所有邮箱的姓名均非必填
            //设置发件人邮箱及名字,非必须

            //todo 需要确认
            $mail->setFrom($mail->defaultSender['noreplay']['email'], $mail->defaultSender['noreplay']['name']);
            //添加收件人邮箱和姓名，至少要有一个收件人
            $emailArr = explode(';', $emails);
            $emailArr = array_unique($emailArr);
            if (count($emailArr) < 1) {
                return ['status' => false, 'message' => '邮件发送失败', 'errorMsg' => '收件人不可为空'];
            }
            foreach ($emailArr as $item) {
                if (empty($item)) {
                    continue;
                }
                $mail->addAddress($item);
            }

            //添加邮件回复人，非必填
            //$mail->addReplyTo('info@example.com', 'Information');

            //添加抄送和密送人，非必填
            $ccArr = explode(';', $cc);
            $ccArr = array_unique($ccArr);
            if (count($ccArr) > 0) {
                foreach ($ccArr as $item) {
                    if (empty($item)) {
                        continue;
                    }
                    $mail->addCC($item);
                }
            }
            //$mail->addBCC('bcc@example.com');

            //添加文件内容 附件
            //$mail->addStringAttachment('ssdsadasdasdasd', 'abc.txt');
            //添加附件
            //$mail->addAttachment(ROOT_PATH . '/Readme.md', '使用需求.md');

            //添加内置图片，需要一个唯一标识，便于文件定位
            $file_path = ROOT_PATH . "/Data/Image/logo.png";
            $cid = $mail->getUuid();
            $mail->addEmbeddedImage($file_path, $cid, 'logo.png');

            // Content
            $mail->isHTML(true);                                  // Set email format to HTML
            $mail->Subject = $subject;

            $file_path = ROOT_PATH . "/Data/Template/mail.html";
            if (!file_exists($file_path)) {
                return ['status' => false, 'message' => '邮件发送失败', 'errorMsg' => '模板不存在'];
            }

            //将整个文件内容读入到一个字符串中
            $emailBody = file_get_contents($file_path);
            $emailBody = str_replace("{{logo.png}}", "cid:" . $cid, $emailBody);
            $emailBody = str_replace("{{url}}", $url, $emailBody);
            $emailBody = str_replace("{{num}}", $num, $emailBody);

            if (empty($content)) {
                $content = "根据您的招聘要求，我们向您推荐 <span style='font-size:14px;color:#415ff5;'>" . $num . "</span> 名符合条件的目标候选人，";
                $content .= "您可以点击以下链接查看候选人详情，并反馈您的挑选结果。";
            }

            $emailBody = str_replace("{{content}}", $content, $emailBody);

            $mail->Body = $emailBody;

            $mail->setJobsmailFlag(config('mail.flag.cvreviewmail', 0));
            $mail->send();
        } catch (PHPMailerException $e) {
            return ['status' => false, 'message' => '邮件发送失败', 'errorMsg' => $e->getMessage()];
        }
        $sql = 'update ResumeRecommend set retrydate = Now() where id = ?';
        $var = [$recommendId];
        $updateResult = Db::update($sql, $var);
        if (!$updateResult) {
            Log::error('简历推荐重新发送邮件，数据库更新失败.file:' . __FILE__ . 'line:' . __LINE__);
        }
        return ['status' => true, 'message' => '邮件发送成功'];
    }

    public function resendRecommendEmail($recommendId) {
        if (empty($recommendId)) {
            return ([
                'status' => false,
                'message' => '推荐记录id不能为空'
            ]);
        }
        $sql = 'select subid,email,cc,title,memo,caseid from ResumeRecommend where id = ? and recommender = ?';
        $var = [$recommendId, UserAuth::getLoginId()];
        $recommendInfo = Db::selectOne($sql, $var);
        if (empty($recommendInfo)) {
            return ([
                'status' => false,
                'message' => '推荐记录不存在'
            ]);
        }
        if (empty($recommendInfo['email'])) {
            return ([
                'status' => false,
                'message' => '用户邮箱不存在'
            ]);
        }
        $caseResumeIds = explode(',', $recommendInfo['caseid']);
        $nowTime = time();
        $duetime = strtotime(date("Y-m-d", $nowTime)) + 8 * 86400;
        $url = $this->creatRecommendToken($recommendInfo['subid'], $recommendId, $duetime);
        $result = $this->sendMail($recommendId, $recommendInfo['email'], $recommendInfo['cc'], $recommendInfo['title'], $recommendInfo['memo'], $url, count($caseResumeIds));
        return $result;
    }

    public function checkToken($token,$subId,$recommendId) {
        $keyVerify = [];
        $keyVerify['recommendid'] = $recommendId;
        $keyVerify['subid'] = $subId;
        $verifyToken = UrlCrypt::generateToken($keyVerify);
        if($token == $verifyToken) {
            return true;
        }
        return false;
    }
}